今天我們要說明如何用sklearn 的 TfidfVectorizer 將電影資訊向量化。
要怎麼做呢?只要4個步驟。
我準備了11198篇的電影資訊,然後把電影資訊、卡司、演員表等,全部都串成一個字串。
將字串斷詞過後的,每一篇文章就會長成像這個樣子。
故事 由 《 魔戒 首 部 曲 : 魔戒 現身 》 展開 , 一 位 名叫 的 年輕人 , 無意 間 得到 一 枚 有 著 神秘 力量 的 戒指 , 卻 發現 這 枚 戒指 原來 是 黑暗 魔王 所 擁有 。 幾經 波折 後 , 他 決定 摧毀 魔戒 , 以免 奪回去 鞏固 自己 的 勢力 。 巫師 、 精靈 、 矮人 、 和 人類 於是 組成 魔戒 遠征隊 , 協助 佛羅多 前往 索倫 統治 的 「 中土 世界 」 , 將 魔戒 丟入 末日 火山 摧毀 。 旅途 中 派出 怪獸 追殺 佛羅多 一 群 人 , 魔戒 也 開始 腐蝕 人心 , 讓 人 產生 難以 抵擋 的 慾望 , 考驗 著 每 位 接觸 戒指 的 意志力 。 Peter Jackson 、 Sean Astin 、 Sean Bean 、 Cate Blanchett 奧蘭多布魯 ( Orlando Bloom ) 、 ( Marton Csokas) 、 ( Ian Holm ) 、 李 ( Christopher Lee ) 、 瑟克斯 ( Andy Serkis ) 、 維果 莫天森 ( Viggo Mortensen ) 、 ( Hugo Weaving )
為了等下展示方便,seg_line_list 就是我放資料的變數。
print(len(seg_line_list)) ## 有1萬多篇的電影資料構成的串列
11198
共有 11198 篇
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
vectorizer = TfidfVectorizer()
feature_matrix = vectorizer.fit_transform(seg_line_list)
feature_matrix
<11198x117753 sparse matrix of type '<class 'numpy.float64'>'
with 1529011 stored elements in Compressed Sparse Row format>
這什麼意思呢? 11198 是我的電影資料篇數,117753 是這些文章找出的所有的詞的總數。
feature_matrix[0] 裡放著什麼呢?
print(feature_matrix[0])
他是一個稀疏矩陣,所以表示的方法跟一般的串列不一樣。
(0, 35755) 0.062127121469352994
(0, 73377) 0.04926651860664991
(0, 81134) 0.046503387146599545
(0, 39644) 0.022203660939488494
(0, 15632) 0.11405749636828087
(0, 15223) 0.11405749636828087
(0, 112131) 0.11571064071739166
(0, 11140) 0.13516798172170535
(0, 20872) 0.08270790227245117
(0, 7243) 0.09312136735253172
(0, 19811) 0.09460015536396717
(0, 7807) 0.0917836408770831
先忽略掉每一行的第一個0,你看到第一個數字,例如35755代表的是第355755號的詞,而後面帶有小數點的數字就是TFIDF 值,就是這個詞在這篇文章的重要程度。
那35755是哪個詞呢? 我們可以用 get_feature_names_out() 找出字典
words = vectorizer.get_feature_names_out()
print(words[35755])
print(words[73377])
傳記
歷史
similarity = cosine_similarity(feature_matrix)
print(similarity)
[[1. 0.04314573 0.02149657 ... 0.02443829 0.00418044 0.00128481]
[0.04314573 1. 0.0279604 ... 0.03061228 0.00751541 0.01318771]
[0.02149657 0.0279604 1. ... 0.01694194 0.01199874 0.02370222]
...
[0.02443829 0.03061228 0.01694194 ... 1. 0.00225818 0.02985038]
[0.00418044 0.00751541 0.01199874 ... 0.00225818 1. 0.0108662 ]
[0.00128481 0.01318771 0.02370222 ... 0.02985038 0.0108662 1. ]]
把特徵矩陣丟進去,得到相似矩陣。
def get_related_movie_index(movie_index, similarity):
related_limit = 11
movie_similarity = list(enumerate(similarity[movie_index]))
sorted_movie_similarity = sorted(movie_similarity, key = lambda x: x[1], reverse= True)
return [m_index for m_index, score in sorted_movie_similarity[0:related_limit]]
因為我知道 2861 是美國隊長,所以用以下程式找出和美國隊長相似的電影:
get_related_movie_index(2861, similarity)
[2861, 4070, 5126, 3168, 1889, 6865, 2508, 4809, 2867, 2665]
除了第1個2861是美國隊長外,從4070開始分別是:
看起來除了 真愛BJ4 及 麥克邁:超能壞蛋 外 似乎還不錯!
看起來效果還是不錯,我們明天再來仔細研究一下為什麼會這樣推薦?